package com.awenhui.demo.core.utils;

import com.sun.org.apache.xpath.internal.operations.Bool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 执行MySql数据备份命令工具类
 * @author 何祖文 on 2019年1月8日 下午3:36:45
 */
public class DatabaseTool {
	
//    @Value("${jdbc.mysqlIp}")
//    /**IP地址**/
//    private String mysqlIp;
//
//    @Value("${jdbc.mysqlPort}")
//    /**端口**/
//    private String mysqlPort;
//
//    @Value("${jdbc.username}")
//    /**用户名**/
//    private String userName;
//
//    @Value("${jdbc.password}")
//    /**IP密码**/
//    private String password;
//
//    @Value("${jdbc.database}")
//    /**数据库名**/
//    private String database;
//
//    @Value("${jdbc.resultFile}")
//    /**全路径**/
//    private String resultFile;
//
//    @Value("${jdbc.isOpen}")
//    /**是否开启**/
//    private boolean isOpen;
    
    /**线程工具类**/
	@Autowired
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;
	
	/**文件名称前缀**/
	private static final String FILE_NAME = "db_backups_";
	/**文件格式最后名称**/
	private static final String FILE_SUFFIX = ".sql";
	/**编码方式**/
	private static final String DEFAULT_ENCODING = "utf-8";
	
	/**日志对象**/
	private Logger log = LoggerFactory.getLogger(DatabaseTool.class);

	/**
	 * 备份数据库 ,控制台执行命令格式 "mysql的bin目录/mysqldump --databases  -h主机ip -P端口  -u用户名 -p密码  --default-character-set=字符集  数据库名
	 * @param isOpen 是否启用备份
	 * @param host 主机ip，本机填localhost
	 * @param userName 用户名
	 * @param password 密码
	 * @param port 端口
	 * @param database 要备份的数据库
	 * @param backupFileDir 备份文件存储的路径（文件名根据日期自动命名）
	 */
	public void backup(boolean isOpen, String host,String userName,String password,String port,String database,String backupFileDir) {
		log.info("=======================SQL备份开始执行=======================");
		if(!isOpen)return;
		InputStream in = null;
		try {
			Runtime rt = Runtime.getRuntime();
			String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) ;
			// 调用mysql的安装目录的命令
			StringBuilder sb = new StringBuilder();
			sb.append("mysqldump --databases -h").
			append(host).append(" -P").append(port).append(" -u").append(userName).append(" -p").
			// 设置导出编码为utf-8。这里必须是utf-8
			append(password).append(" --add-drop-database --default-character-set=utf8 ").
			append(database).append(" --result-file=").append(backupFileDir).
			append(FILE_NAME).append(database).append("_").append(dateStr).append(FILE_SUFFIX);
			Process process = rt.exec(sb.toString());
			// 控制台的输出信息作为输入流
			in = process.getInputStream();
			// 错误流另开线程，不然会阻塞
			threadPoolTaskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					// 具体实现
					InputStreamReader isr = null;
			        BufferedReader buff = null;
			        try {
			            isr = new InputStreamReader(process.getErrorStream(),DEFAULT_ENCODING);
			            buff = new BufferedReader(isr);
			            String line;
			            while ((line = buff.readLine()) != null) {
			                if (line.indexOf("Warning") != 0) {
			                    log.error("错误流线程方法异常"+line);
			                    return;
			                }
			            }
			        } catch (Exception e) {
			            log.error("错误流线程方法异常"+e.getMessage());
			        } finally {
			            try {
			                if (buff != null) {
			                    buff.close();
			                }
			                if (isr != null) {
			                    isr.close();
			                }
			            } catch (IOException e) {
			            	log.error("错误流线程方法异常"+e.getMessage());
			            }
			        }
				}
			});
			
		} catch (Exception e) {
			log.error("错误流线程方法异常"+e.getMessage());
			e.printStackTrace();
		}finally{
			try {
				if(in != null){
					in.close();
				}
			} catch (IOException e) {
				log.error("关闭流出错"+e.getMessage());
			}
		}
		log.info("=======================SQL备份执行结束=======================");
	}
}